﻿using Core.Info;
using Core.Utility;
using Core.Utility.Crypto;
using Core.Utility.Helper;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Security.Principal;
using FreeSql.DataAnnotations;
using Core.Log;
using System.Data;
using Core.Utility.Crypto.Core;
using FreeSql;
using System.ComponentModel.DataAnnotations;
using Core.Database.Model;
using Microsoft.Extensions.Logging;

namespace Core.Database
{
    /// <summary>
    /// 数据库工厂类
    /// </summary>
    public static class DatabaseFactory
    {
        #region 常量
        /// <summary>
        /// 公钥
        /// </summary>
        public const string PublicKey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr+5UJvay8vUDjgDuIoAoeGVsWRG7vUjluJoxDgs5KImZI6F3H9DqYNkFoZ5GCtgpu9G/6MWExm5xOdnAxKWPI9QQqV3EworRUCz47Le8EZNRghhRLXyNyR2QcMST0nZBfJrtfgNe7YnyiAt0OXn/pQCu11vbdPcuTJmMnZ3kZ5O9NM3Q46SDoHxnBeRbKUWq00qs6blAb4Hyv9Wk0UDpInkdNRcwqIP3wLhFZUB/oJaL7OZbzgdgTisTJm5bEmOIYj/ttt8BMNEDDT5iVaYlB5wVzXwrMDz/xX6mDpxS6wqb6P8fbCcsYqHlWQXW/xAlks837f+45mBb76/hBFtBtQIDAQAB";

        /// <summary>
        /// 私钥
        /// </summary>
        private const string PrivateKey = @"MIIEpAIBAAKCAQEAr+5UJvay8vUDjgDuIoAoeGVsWRG7vUjluJoxDgs5KImZI6F3H9DqYNkFoZ5GCtgpu9G/6MWExm5xOdnAxKWPI9QQqV3EworRUCz47Le8EZNRghhRLXyNyR2QcMST0nZBfJrtfgNe7YnyiAt0OXn/pQCu11vbdPcuTJmMnZ3kZ5O9NM3Q46SDoHxnBeRbKUWq00qs6blAb4Hyv9Wk0UDpInkdNRcwqIP3wLhFZUB/oJaL7OZbzgdgTisTJm5bEmOIYj/ttt8BMNEDDT5iVaYlB5wVzXwrMDz/xX6mDpxS6wqb6P8fbCcsYqHlWQXW/xAlks837f+45mBb76/hBFtBtQIDAQABAoIBAQCo8M7kf6AFyJx6P5Btlu3F93cc7PeAY8EdDQwwNTzVHZTt7z5qUf7Ps3dB5K/T+BHTZy7HQu0mc6XM7Lq821LiD+FUElRAkHdBa346KpGxuurZZ6qEaIfq6bXrZAmjX6WxF0EZ8fi1V/OLCpy4GNwRwd8jtPS/lCFks0qhjJ5pipDeJomlx1+/k028MGcVFw1rWN32mui9mSNXGLNHCxfLEqlW7Oaqp2bNKYxFwgAze8CmvweRFJoDQstUm9m1HRMCiTebTA2pzi6y8VIYsQxhrWbq9/Gvb4dI7SRsfA2YfKXmp2Swn+d5g+aW07iIxceA1qkaSZkS7hQKVZ6viDAdAoGBANU3Qw1ZJDlovlSVE5Bg70YF1AS/Lk2ulzpfatn1akk3m3FaC76PpBMqPaY6rY8pb7qocKEYvqFcTqkwiXbPLOQxwArzO9xuPyjclx9SkIlkYXRrSKtZjYhlSIyiKUo5qTNDOEfKGLK09zuTR1PooelRGBBXHUQLpjjycdObo7p7AoGBANM7xRbKrMkfJfJSwPzPh2FjWFzS/uZm0LDE07dYscmEsl0Xl9w8inqltzKrECOH5iaaqY1TvcOxReC5EC8koenNuU+D5me2fCDLbwtbKg58Rby4zjp26W4GsGnBpM+/1zHn3H5xJZFiSM2hoPt396xy3LaKdnNKS2YJksXSrhWPAoGAd81NR7rGt9s61pvNGlrdFyM/NkuV4OAw6QOkLkPPLMSp+s71umVLc9lQOo7N5psJxH/QiTQ2KMSNDlPPaYqPVsj9dymkgP8RTgxkfZ0OyaQ1fgyqEF2JQRJn6V1UhfhQMhWbEftkVUWJhVgDxAn6r/Z45vWL5CgHhgf0HUpefPECgYEAiSTHQ5L3N+VnR7t+3SUIaqyLlEjRglnCqOJB60pEs+fZviMxT6Zm6lZpaRYzdj4nqWzFJKL4E/QmwE6nOVR5Y0lURVIH59JNKSWrxR29YoZA6NS74K2PxQXGyAMXtGKDnz1ApT9k+s1rI0cLM/mh7m7s6f9gBF56MZeJmbK9n/UCgYBcDAN66N4gxcchH7lmeUxIyxlI64BgXjHvYA1LjbgdC1ZXeh1xpcIyKy/MwetE416fdE7QNTyLdyUH8MqXffB3JzARBQH4ayNvpyibq7HdjW6g6XBu5ZGQ3HDlAj1Jgk9mXGFqzMfBcgAqMLo4/rkKUQYr3XXmobGjOXNzm6SWpQ==";

        /// <summary>
        /// AES加密的Key
        /// </summary>
        private const string AesKey = @"G1NG77+9a1RT77+9JO+/vTBR77+9P8KU77+977+9Zu+/ve+/ve+/vTXvv70377+977+9QEbvv71h77+9";

        /// <summary>
        /// AES,IV
        /// </summary>
        private const string AesIV = @"77+9HiMMaO+/vXIo77+977+9SX3blu+/vQc=";
        #endregion

        /// <summary>
        /// 配置文件目录：应用根目录/Config/db/
        /// </summary>
        public static string ConfigFileDirectory { get;private set; }

        /// <summary>
        /// 配置文件名称
        /// </summary>
        public const string ConfigFileName = "db.config.json";


        private static object _lock = new object();

        /// <summary>
        /// 获取数据库配置文件的配置，此方法总是读取配置文件，进行反序列化；频繁读取数据库配置，不建议使用此方式获取
        /// 查询失败返回 
        /// <code>
        /// new List&lt;DatabaseConfigModel&gt;()
        /// </code>
        /// </summary>
        public static IList<DatabaseConfig> Configs
        {
            get
            {
                try
                {
                    var configString = ReadConfig();
                    if (!string.IsNullOrEmpty(configString))
                    {
                        var configs = JsonHelper.Deserialize<List<DatabaseConfig>>(configString);
                        if (configs == null)
                        {
                            configs = new List<DatabaseConfig>();
                        }
                        #region 遍历配置，进行解密
                        for (int i = 0; i < configs.Count; i++)
                        {
                            configs[i] = Decrypt(configs[i]) ?? configs[i];
                        }
                        #endregion 遍历配置，进行解密 
                        return configs;
                    }
                    else
                    {
                        return new List<DatabaseConfig>();
                    }
                }
                catch(Exception ex)
                {
                    throw new Exception("读取/解析数据库JSON配置文件出错", ex);
                }
            }
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        /// <returns></returns>
        public static bool SaveConfig(List<DatabaseConfig> configs)
        {
            if (!Directory.Exists(ConfigFileDirectory))
            {
                Directory.CreateDirectory(ConfigFileDirectory);
            }
            string initFileFullPath = Path.Combine(ConfigFileDirectory, $"{ConfigFileName.Replace(".json", ".init.json")}");
            if (!File.Exists(initFileFullPath))
            {
                //不包含初始配置文件，将当前配置文件做初始配置文件备份
                File.Copy(Path.Combine(ConfigFileDirectory, ConfigFileName), initFileFullPath,true);
            }
            string backFileFullPath = Path.Combine(ConfigFileDirectory, $"{ConfigFileName.Replace(".json", ".back.json")}");
            //不包含配置文件备份，将当前配置文件做配置文件备份
            File.Copy(Path.Combine(ConfigFileDirectory, ConfigFileName), backFileFullPath, true);
            #region 遍历配置，进行加密
            for (int i = 0; i < configs.Count; i++)
            {
                configs[i] = Encrypt(configs[i]) ?? configs[i];
            }
            #endregion 遍历配置，进行加密 
            string? jsonContent = JsonHelper.EexceptionSerialize(configs);
            return FileHelper.WriteFileReturnBool(Path.Combine(ConfigFileDirectory, ConfigFileName), jsonContent);            
        }

        /// <summary>
        /// 读取配置文件
        /// </summary>
        /// <returns></returns>
        private static string? ReadConfig()
        {
            string? res = null;
            if (!Directory.Exists(ConfigFileDirectory))
            {
                Directory.CreateDirectory(ConfigFileDirectory);
            }
            string configFilePath = Path.Combine(ConfigFileDirectory, ConfigFileName);
            if (File.Exists(configFilePath))
            {
                res = FileHelper.ReadFileToString(configFilePath);
            }
            return res;
        }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        static DatabaseFactory()
        {
            ConfigFileDirectory = Path.Combine(AppInfo.ConfigDirectory);
            //if(config == null)
            //{
            //    lock(_lock)
            //    {
            //        if(config == null)
            //        {
            //            config = new ConfigurationBuilder()
            //                .AddInMemoryCollection()//将配置文件数据加载到内存中
            //                .SetBasePath(ConfigFileDirectory)//指定配置文件所在的目录
            //                .AddJsonFile(ConfigFileName, optional:true,reloadOnChange:true) //指定加载的配置文件  --划重点..记得始终复制
            //                .Build();//编译成对象                          
            //        }
            //    }
            //}
        }

        /// <summary>
        /// 加密数据库配置
        /// </summary>
        /// <param name="config"></param>
        /// <param name="saltStr">加盐字符串</param>
        /// <returns></returns>
        public static DatabaseConfig Encrypt(this DatabaseConfig? config,string saltStr = "")
        {
            if (!string.IsNullOrWhiteSpace(config?.Address))
            {
                config.Address = Encrypt(config.Address, nameof(config.Address) + saltStr);
            }
            if (!string.IsNullOrWhiteSpace(config?.Port))
            {
                config.Port = Encrypt(config?.Port, nameof(config.Port) + saltStr);
            }
            if (!string.IsNullOrWhiteSpace(config?.UserName))
            {
                config.UserName = Encrypt(config.UserName, nameof(config.UserName) + "username" + saltStr);
            }
            if (!string.IsNullOrWhiteSpace(config?.Password))
            {
                config.Password = Encrypt(config.Password, nameof(config.Password) + "pwdpwd" + saltStr);
            }
            return config ?? new DatabaseConfig();
        }

        /// <summary>
        /// 解密数据库配置
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        public static DatabaseConfig? Decrypt(this DatabaseConfig? config, string saltStr = "")
        {

            if (!string.IsNullOrWhiteSpace(config?.Address))
            {
                config.Address = Decrypt(config.Address, nameof(config.Address) + saltStr);
            }

            if (!string.IsNullOrWhiteSpace(config?.Port))
            {
                config.Port = Decrypt(config?.Port?.ToString(), nameof(config.Port) + saltStr);
            }

            if (!string.IsNullOrWhiteSpace(config?.UserName))
            {
                config.UserName = Decrypt(config.UserName, nameof(config.UserName) + "username" + saltStr);
            }

            if (!string.IsNullOrWhiteSpace(config?.Password))
            {
                config.Password = Decrypt(config.Password, nameof(config.Password) + "pwdpwd" + saltStr);
            }
            return config;
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="value">加密的原始值</param>
        /// <param name="propertyName">加密的属性名，用于加盐</param>
        /// <returns></returns>
        public static string? Encrypt(string? value,string? propertyName)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }
            var aes256Provider = CryptoFactory.CreateSymmetric(SymmetricProviderType.AES256);
            aes256Provider.OutType = OutType.Base64;
            string aesKey = AesKey + propertyName;
            string aesIV = AesIV + propertyName;
            var aesEncryptRes = aes256Provider.Encrypt(value, aesKey, aesIV);
            var rsa2Provider = CryptoFactory.CreateAsymmetric(AsymmetricProviderType.RSA2);
            rsa2Provider.KeyType = RSAKeyType.Base64;
            rsa2Provider.OutType = OutType.Base64;            
            var rsa2Res = rsa2Provider.Encrypt(aesEncryptRes, PublicKey);
            return rsa2Res;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="value">解密的原始值</param>
        /// <param name="propertyName">解密的属性名，用于加盐解密</param>
        /// <returns></returns>
        public static string? Decrypt(string? value,string? propertyName)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }
            try
            {
                var rsa2Provider = CryptoFactory.CreateAsymmetric(AsymmetricProviderType.RSA2);
                rsa2Provider.KeyType = RSAKeyType.Base64;
                rsa2Provider.OutType = OutType.Base64;
                var rsa2Res = rsa2Provider.Decrypt(value, PrivateKey);
                var aes256Provider = CryptoFactory.CreateSymmetric(SymmetricProviderType.AES256);
                aes256Provider.OutType = OutType.Base64;
                string aesKey = AesKey + propertyName;
                string aesIV = AesIV + propertyName;
                var aesEncryptRes = aes256Provider.Decrypt(rsa2Res, aesKey, aesIV);
                return aesEncryptRes;
            }
            catch
            {
                //解密失败，原样返回
                return value;
            }
        }

        /// <summary>
        /// 测试连接,传入的数据库地址、端口、用户名、密码等，应当是解密后的
        /// </summary>
        /// <param name="config"></param>
        /// <param name="dbCommandTimeout">数据库命令超时时间</param>
        /// <returns>连接成功返回指定用户权限的数据库</returns>
        public static ReturnResultInfo<List<string>> TestConnection(this DatabaseConfig config,int dbCommandTimeout = 0)
        {
            ReturnResultInfo<List<string>> res = new ReturnResultInfo<List<string>>();
            var testConfig = config.DeepCopyByReflectionT();
            testConfig.Timeout = (uint)Math.Abs(dbCommandTimeout);
            string connectionString = GenerateConnectionString(config);
            if (string.IsNullOrEmpty(connectionString))
            {
                res.Message = $"{config.DatabaseType.ToString()} 是不支持的数据库类型";
            }
            else
            {
                FreeSql.DataType? dbType = DatabaseTypeToFreeSqlDataType(config.DatabaseType);
                if (dbType == null)
                {
                    res.Message = $"未匹配到对应的数据库,{config.DatabaseType} => FreeSql.DataType";
                }
                else
                {
                    try
                    {
                        using (var fsql = new FreeSql.FreeSqlBuilder()
                           .UseConnectionString(dbType.GetValueOrDefault(),
                           connectionString).Build())
                        {
                            var dbTest = fsql.Ado.ExecuteConnectTest(dbCommandTimeout);
                            if (dbTest == true)
                            {
                                res.Data = fsql.DbFirst.GetDatabases();
                                res.Message = "数据库连接成功！";
                                res.Successed = true;
                            }
                            else
                            {
                                res.Message = "数据库连接失败；请检查数据库连接配置！";
                                res.Info = "数据库连接失败；请检查数据库连接配置！";
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        res.Message = $"数据库连接失败，失败原因为：{Environment.NewLine}{ex.DetailMessage()}";
                        res.Info = $"数据库连接失败，失败原因为：{Environment.NewLine}{ex.DetailInfo()}";
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// 数据库类型转Freesql数据库类型
        /// </summary>
        /// <returns></returns>
        public static FreeSql.DataType? DatabaseTypeToFreeSqlDataType(DatabaseType? databaseType)
        {
            FreeSql.DataType? dbType = null;
            switch (databaseType)
            {
                case DatabaseType.PostgreSQL:
                    dbType = FreeSql.DataType.PostgreSQL;
                    break;
                case DatabaseType.MySql:
                    dbType = FreeSql.DataType.MySql;
                    break;
                case DatabaseType.Oracle:
                    dbType = FreeSql.DataType.Oracle;
                    break;
                case DatabaseType.Sqlite:
                    dbType = FreeSql.DataType.Sqlite;
                    break;
                case DatabaseType.SqlServer:
                    dbType = FreeSql.DataType.SqlServer;
                    break;
                default:
                    break;
            }
            return dbType;
        }

        /// <summary>
        /// 生成连接字符串,传入的数据库地址、端口、用户名、密码等，应当是解密后的
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        public static string GenerateConnectionString(this DatabaseConfig config)
        {
            string res = "";
            uint maxPoolSize = 5;
            maxPoolSize = config.MaxPoolSize.GetValueOrDefault(5);
            string? port = config.Port;
            switch (config.DatabaseType)
            {
                case DatabaseType.MySql:
                    if(string.IsNullOrEmpty(port) || port == "0")
                    {
                        port = "3306";
                    }
                    res = $"Data Source={config.Address};Port={port};User ID={config.UserName};Password={config.Password};Initial Catalog={(string.IsNullOrEmpty(config.DatabaseName) ? "mysql" : config.DatabaseName)};SslMode=none;Max pool size={maxPoolSize};Connection Timeout={config.Timeout};Charset=utf8mb4;";
                    break;
                case DatabaseType.SqlServer:
                    if (string.IsNullOrEmpty(port) || port == "0")
                    {
                        port = "1433";
                    }
                    res = $"Data Source={config.Address};User Id={config.UserName};Password={config.Password};Initial Catalog={config.DatabaseName};Encrypt=True;TrustServerCertificate=True;Pooling=true;Min Pool Size=1;Connect Timeout={config.Timeout}";
                    break;

                case DatabaseType.PostgreSQL:
                    if (string.IsNullOrEmpty(port) || port == "0")
                    {
                        port = "5432";
                    }
                    res = $"Host={config.Address};Port={port};Username={config.UserName};Password={config.Password};Database={(string.IsNullOrEmpty(config.DatabaseName) ? "postgres" : config.DatabaseName)};Pooling=true;Maximum Pool Size={maxPoolSize};CommandTimeout={config.Timeout};";
                    break;
                case DatabaseType.Oracle:
                    if (string.IsNullOrEmpty(port) || port == "0")
                    {
                        port = "1521";
                    }
                    res = $"user id={config.UserName};password={config.Password};data source=//{config.Address}:{port}/{config.DatabaseName};Pooling=true;Max Pool Size={maxPoolSize};Connection Timeout={config.Timeout};"; 
                    break;
                case DatabaseType.Sqlite:
                    string? address = config?.Address;
                    if(string.IsNullOrWhiteSpace(address))
                    {
                        address = AppInfo.RootDirectory;
                    }

                    if(!address.EndsWith(Path.DirectorySeparatorChar) || !address.EndsWith("\\") || !address.EndsWith("//"))
                    {
                        address = address + Path.DirectorySeparatorChar;
                    }

                    string subDirectory = address;
                    bool replaceRootDirectory = false;
                    //判断是否需要替换根目录
                    if (address.StartsWith("."))
                    {
                        subDirectory = address.Substring(1);
                        replaceRootDirectory = true;
                    }
                    else if (address.ToLower().StartsWith("lcoalhost"))
                    {
                        subDirectory = address.Substring("lcoalhost".Length);
                        replaceRootDirectory = true;
                    }
                    //截取子目录，首字符不包含 / 或 \
                    if (subDirectory?.StartsWith(Path.DirectorySeparatorChar) == true || subDirectory?.StartsWith("\\") == true || subDirectory?.StartsWith("//") == true)
                    {
                        subDirectory = subDirectory.Substring(1);
                    }
                    if(replaceRootDirectory)
                    {
                        //替换根目录，拼接子目录
                        address = Path.Combine(AppInfo.RootDirectory);
                        if(!string.IsNullOrWhiteSpace(subDirectory))
                        {
                            address = Path.Combine(address,subDirectory);
                        }
                    }

                    string path = address;

                    if(!string.IsNullOrWhiteSpace(config?.DatabaseName))
                    {
                        path = Path.Combine(address, config.DatabaseName);
                    }
                    try
                    {
                        string? pathDirectory = Path.GetDirectoryName(address);
                        if (pathDirectory != null && !Directory.Exists(pathDirectory))
                        {
                            Directory.CreateDirectory(pathDirectory);
                        }
                    }
                    catch(Exception ex)
                    {
                        AppTrace.Logger.LogError(ex, $"创建Sqlite目录出错，拟创建路径：{address}");
                    }

                    res = $"Data Source={path};Pooling=true;Max Pool Size={maxPoolSize};Timeout={(config?.Timeout ??  30 )* 1000};";
                    break;
                default:
                    res = "";
                    break;
            }
            return res;
        }

        /// <summary>
        /// 根据配置及排序，生成主从库的IFreesql
        /// </summary>
        /// <param name="configList"></param>
        /// <param name="useLocalSqlite">若 configList 为null , 使用本地Sqlite进行初始化</param>
        /// <returns></returns>
        public static IFreeSql GenerateFreeSql(List<DatabaseConfig> configList,bool useLocalSqlite = false)
        {
            try
            {
                var freeSqlBuilder = new FreeSqlBuilder();
                if (configList.Count > 0)
                {
                    //进行排序
                    configList = configList.OrderBy(p => p.SortNumber).ToList();
                    //主库：
                    var mainConfig = configList.FirstOrDefault(p => p.SlaveFlag == false);
                    if (mainConfig == null)
                    {
                        //将第一个从库作为主库
                        mainConfig = configList.FirstOrDefault(p => p.SlaveFlag == true);
                        AppTrace.Logger.LogWarning($"未获取到主库配置，使用从库配置作为主库：{Environment.NewLine}DatabaseName:{mainConfig?.DatabaseName}；{Environment.NewLine}Guid:{mainConfig?.Guid}；");
                    }
                    if (mainConfig != null)
                    {
                        StringBuilder dbInfo = new StringBuilder();
                        var mainConfigDbType = mainConfig.DatabaseType.Converter();
                        var mainConfigConnectionString = GenerateConnectionString(mainConfig);
                        freeSqlBuilder = freeSqlBuilder.UseConnectionString(mainConfigDbType, mainConfigConnectionString);
                        //将主库从列表中移除，将剩余的库作为从库加载
                        configList.Remove(mainConfig);
                        dbInfo.AppendLine($"主库配置信息：{Environment.NewLine}ConnectionName:{mainConfig?.ConnectionName}；{Environment.NewLine}DatabaseName:{mainConfig?.DatabaseName}；{Environment.NewLine}Guid:{mainConfig?.Guid}；");
                        List<string> slaveConfigConnectionStringList = new List<string>();
                        int slaveNumber = 0;
                        foreach (var slaveConfigItem in configList)
                        {
                            slaveNumber++;
                            var slaveConfigConnectionString = GenerateConnectionString(slaveConfigItem);
                            if (!string.IsNullOrWhiteSpace(slaveConfigConnectionString))
                            {
                                slaveConfigConnectionStringList.Add(slaveConfigConnectionString);
                            }
                            dbInfo.AppendLine($"从库【{slaveNumber}】配置信息：{Environment.NewLine}ConnectionName:{mainConfig?.ConnectionName}；{Environment.NewLine}DatabaseName:{mainConfig?.DatabaseName}；{Environment.NewLine}Guid:{mainConfig?.Guid}；");
                        }
                        if (slaveConfigConnectionStringList.Count > 0)
                        {
                            freeSqlBuilder = freeSqlBuilder.UseSlave(slaveConfigConnectionStringList.ToArray());
                        }
                        AppTrace.Logger.LogInformation(dbInfo.ToString());
                    }
                }
                else
                {
                    //freeSqlBuilder.UseConnectionString(FreeSql.DataType.Custom, "");
                    if (useLocalSqlite == false)
                    {
                        throw new Exception("数据库列表为空，无法进行实例化");
                    }
                    else
                    {
                        var localSqlite = DatabaseConfig.LocalSqlite;
                        var localSqliteConnectionString = GenerateConnectionString(localSqlite);
                        freeSqlBuilder.UseConnectionString(FreeSql.DataType.Sqlite, localSqliteConnectionString);
                        AppTrace.Logger.LogWarning($"数据库配置为空，使用本地Sqlite进行初始化");
                    }
                }
                freeSqlBuilder = freeSqlBuilder.UseMonitorCommand(cmd =>
                {
                    if (RunTimeInfo.IsDebug || RunTimeInfo.IsDevelopment)
                    {
                        if (RunTimeInfo.IsDebug || RunTimeInfo.IsDevelopment)
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.AppendLine("数据存储执行SQL：");
                            sb.AppendLine($"CommandType：{cmd.CommandType}");
                            sb.AppendLine($"CommandText：{Environment.NewLine}{cmd.CommandText}");
                            AppTrace.Logger.LogInformation(sb.ToString());
                        }
                    }
                });
                IFreeSql freeSql = freeSqlBuilder.Build();
                return freeSql;
            }
            catch(Exception ex)
            {
                AppTrace.Logger.LogCritical(ex,"实例化数据库失败");
                throw new Exception("实例化数据库失败", ex);
            }
        }
    }
}
